<script setup lang="ts" name="InfraApiErrorLog">
import { storeToRefs } from 'pinia'
import { useAppStoreWithOut } from '@/store/modules/app'
import { dateTimeFormatter } from '@/utils/dateUtil'
import { ErrorLogApi, ApiErrorLogType } from '@/api/infra/apiLog/error'
import { dataToFile } from '@/components/Excel/src/helper'
import ApiErrorLogDetail from './ApiErrorLogDetail.vue'
import { checkPermit } from '@/utils/permit'
import { DICT_TYPE } from '@/enums/dictEnums'
import { InfraApiErrorLogProcessStatusEnum } from '@/enums/infraEnums'
import { getIntDictOptions } from '@/utils/dict'
const appStore = useAppStoreWithOut()
const { systemConfig } = storeToRefs(appStore)

const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const total = ref<number>(0) // 列表的总页数
const list = ref<ApiErrorLogType[]>([]) // 表格数据
const queryLoading = ref(false) // 列表加载中：1）列表数据加载；2）查询按钮禁用；3）重置按钮禁用
const queryParams = ref({
  pageIndex: 1,
  pageSize: 20,
  userId: undefined,
  userType: undefined,
  applicationName: '',
  processStatus: undefined,
  exceptionTime: undefined
})
const queryFormRef = ref() // 搜索的表单

/** 查询列表 */
const getList = async () => {
  queryLoading.value = true
  try {
    const data = await ErrorLogApi.page(queryParams.value)
    list.value = data.list
    total.value = data.total
  } finally {
    queryLoading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.value.pageIndex = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryParams.value.pageIndex = 1
  queryParams.value.pageSize = 20
  queryParams.value.userId = undefined
  queryParams.value.userType = undefined
  queryParams.value.applicationName = ''
  queryParams.value.processStatus = undefined
  queryParams.value.exceptionTime = undefined
  handleQuery()
}

/** 详情操作 */
const detailRef = ref()
const openDetail = (data) => {
  detailRef.value.open(data)
}


/** 处理已处理 / 已忽略的操作 **/
const handleProcess = async (id: number, processStatus: number) => {
  try {
    // 操作的二次确认
    const type = processStatus === InfraApiErrorLogProcessStatusEnum.DONE ? t('infra.apiLog.error.action', 'handle') : t('infra.apiLog.error.action', 'ignore')
    await message.confirm(t('infra.apiLog.error.rules', 'confirmHandle', [type]))
    // 执行操作
    await ErrorLogApi.updateStatus(id, processStatus)
    await message.success(type)
    // 刷新列表
    await getList()
  } catch { }
}


const ExcelExportDialogRef = ref()

const filedList = ref([
  { key: 'id', value: t('infra.apiLog', 'id') },
  { key: 'traceId', value: t('infra.apiLog', 'traceId') },
  { key: 'applicationName', value: t('infra.apiLog', 'applicationName') },
  { key: 'userId', value: t('infra.apiLog', 'userId') },
  { key: 'userType', value: t('infra.apiLog', 'userType') },
  { key: 'userIp', value: t('infra.apiLog', 'userIp') },
  { key: 'userAgent', value: t('infra.apiLog', 'userAgent') },
  { key: 'requestMethod', value: t('infra.apiLog', 'requestMethod') },
  { key: 'requestParams', value: t('infra.apiLog', 'requestParams') },
  { key: 'requestUrl', value: t('infra.apiLog', 'requestUrl') },
  { key: 'exceptionTime', value: t('infra.apiLog.error', 'exceptionTime') },
  { key: 'exceptionName', value: t('infra.apiLog.error', 'exceptionName') },
  { key: 'exceptionMessage', value: t('infra.apiLog.error', 'exceptionMessage') },
  { key: 'exceptionRootCauseMessage', value: t('infra.apiLog.error', 'exceptionRootCauseMessage') },
  { key: 'exceptionStackTrace', value: t('infra.apiLog.error', 'exceptionStackTrace') },
  { key: 'exceptionClassName', value: t('infra.apiLog.error', 'exceptionClassName') },
  { key: 'exceptionFileName', value: t('infra.apiLog.error', 'exceptionFileName') },
  { key: 'exceptionMethodName', value: t('infra.apiLog.error', 'exceptionMethodName') },
  { key: 'exceptionLineNumber', value: t('infra.apiLog.error', 'exceptionLineNumber') },
  { key: 'processUserId', value: t('infra.apiLog.error', 'processUser') },
  { key: 'processStatus', value: t('infra.apiLog.error', 'processStatus') },
  { key: 'processTime', value: t('infra.apiLog.error', 'processTime') },
  { key: 'resultCode', value: t('infra.apiLog.error', 'resultCode') }
])
/** 导出按钮操作 */
const handleExport = async () => {
  ExcelExportDialogRef.value.open()
}

const exportDone = async (res) => {
  if (res.dataScope === 1) {
    dataToFile(list.value, res)
  } else if (res.dataScope === 3) {
    const allList = await ErrorLogApi.export(queryParams.value)
    dataToFile(allList, res)
  }
}

/** 初始化 **/
onMounted(async () => {
  await getList()
})
</script>

<template>
  <PageCard>
    <ContentFormTable>
      <template #header>
        <ElForm ref="queryFormRef" :model="queryParams" :inline="true">
          <ElFormItem :label="t('infra.apiLog', 'userId')" prop="userId" class="!w-240px">
            <el-input v-model="queryParams.userId" :placeholder="t('infra.apiLog.rules', 'userId')" clearable @keyup.enter="handleQuery" />
          </ElFormItem>
          <el-form-item :label="t('infra.apiLog', 'userType')" prop="userType" class="!w-240px">
            <el-select v-model="queryParams.userType" :placeholder="t('infra.apiLog.rules', 'userType')" clearable>
              <el-option v-for="dict in getIntDictOptions(DICT_TYPE.USER_TYPE)" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
          <ElFormItem :label="t('infra.apiLog', 'applicationName')" prop="applicationName" class="!w-220px">
            <el-input v-model="queryParams.applicationName" :placeholder="t('infra.apiLog.rules', 'applicationName')" clearable @keyup.enter="handleQuery" />
          </ElFormItem>
          <ElFormItem :label="t('infra.apiLog.error', 'exceptionTime')" prop="exceptionTime">
            <el-date-picker
              v-model="queryParams.exceptionTime"
              :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
              class="!w-240px"
              clearable
              :start-placeholder="t('common', 'startDate')"
              :end-placeholder="t('common', 'endDate')"
              type="daterange"
              value-format="YYYY-MM-DD HH:mm:ss"
              @change="handleQuery" />
          </ElFormItem>
          <el-form-item :label="t('infra.apiLog.error', 'processStatus')" prop="processStatus">
            <el-select v-model="queryParams.processStatus" :placeholder="t('infra.apiLog.error.rules', 'processStatus')" clearable class="!w-180px">
              <el-option v-for="dict in getIntDictOptions(DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS)" :key="dict.value" :label="dict.label" :value="dict.value" />
            </el-select>
          </el-form-item>
          <ElFormItem>
            <el-button type="primary" :disabled="queryLoading" icon="Search" @click="handleQuery">{{ t('action',
              'search') }}</el-button>
            <el-button icon="Refresh" :disabled="queryLoading" @click="resetQuery">{{ t('action', 'reset')
            }}</el-button>
            <CButton v-if="checkPermit(['infra:api-error-log:export'])" type="warning" :disabled="queryLoading" :onClick="handleExport" preIcon="ri:export-line" :title="t('action', 'export')" />
          </ElFormItem>
        </ElForm>
      </template>
      <template #content>
        <el-table v-loading="queryLoading && systemConfig.loadingType === 'module'" :data="list" border>
          <el-table-column prop="id" :label="t('infra.apiLog', 'id')" width="120" align="center" />
          <el-table-column prop="userId" :label="t('infra.apiLog', 'userId')" align="center" />
          <el-table-column prop="userType" :label="t('infra.apiLog', 'userType')" align="center">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.USER_TYPE" :value="scope.row.userType" />
            </template>
          </el-table-column>
          <el-table-column prop="applicationName" :label="t('infra.apiLog', 'applicationName')" align="center" />
          <el-table-column prop="requestMethod" :label="t('infra.apiLog', 'requestMethod')" align="center" />
          <el-table-column prop="requestUrl" :label="t('infra.apiLog', 'requestUrl')" align="center" />
          <el-table-column :label="t('infra.apiLog.error', 'exceptionTime')" align="center" prop="exceptionTime" width="180" :formatter="dateTimeFormatter" />
          <el-table-column :label="t('infra.apiLog.error', 'exceptionName')" align="center" prop="exceptionName" width="180" />
          <el-table-column :label="t('infra.apiLog.error', 'processStatus')" align="center" prop="processStatus">
            <template #default="scope">
              <dict-tag :type="DICT_TYPE.INFRA_API_ERROR_LOG_PROCESS_STATUS" :value="scope.row.processStatus" />
            </template>
          </el-table-column>
          <el-table-column prop="operate" :label="t('common', 'operate')" :width="checkPermit(['infra:api-error-log:update-status']) ? 220 : 90" align="left" fixed="right">
            <template #default="scope">
              <el-button type="primary" @click="openDetail(scope.row)">{{ t('action', 'detail') }}</el-button>
              <el-button v-if="scope.row.processStatus === InfraApiErrorLogProcessStatusEnum.INIT && checkPermit(['infra:api-error-log:update-status'])" link type="primary" @click="handleProcess(scope.row.id, InfraApiErrorLogProcessStatusEnum.DONE)">
                {{ t('infra.apiLog.error.action', 'handle') }}
              </el-button>
              <el-button v-if="scope.row.processStatus === InfraApiErrorLogProcessStatusEnum.INIT && checkPermit(['infra:api-error-log:update-status'])" link type="primary" @click="handleProcess(scope.row.id, InfraApiErrorLogProcessStatusEnum.IGNORE)">
                {{ t('infra.apiLog.error.action', 'ignore') }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </template>
      <template #footer>
        <Pagination v-model:limit="queryParams.pageSize" v-model:page="queryParams.pageIndex" :total="total" :disabled="queryLoading" @pagination="getList" />
        <ApiErrorLogDetail ref="detailRef" />
        <ExcelExportDialog ref="ExcelExportDialogRef" :filename="t('infra.apiLog.error', 'title')" :hasSelected="false" :fieldList="filedList" @success="exportDone" />
      </template>
    </ContentFormTable>
  </PageCard>
</template>

<style scoped lang="scss">
.el-table {
  width: 100%;
  height: 100%;
}
</style>
